package com.lvtu.monitor.shiro.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Repository;

import com.lvtu.monitor.shiro.dao.CacheHelper;
import com.lvtu.monitor.shiro.dao.CacheHelper.CacheType;
import com.lvtu.monitor.shiro.dao.ResourceDao;
import com.lvtu.monitor.shiro.entity.Resource;

/**
 * <p>Resource: Zhang Kaitao
 * <p>Date: 14-1-28
 * <p>Version: 1.0
 */
@Repository
public class ResourceDaoImpl implements ResourceDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public Resource createResource(final Resource resource) {
        final String sql = "insert into sys_resource(id, name, type, url, permission, parent_id, parent_ids, available) values(?,?,?,?,?,?,?,?)";
        //System.out.println("[SQL:]" + sql);
        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement psst = connection.prepareStatement(sql, new String[]{"id"});
                int count = 1;
                psst.setLong(count++, resource.getId());
                psst.setString(count++, resource.getName());
                psst.setString(count++, resource.getType().name());
                psst.setString(count++, resource.getUrl());
                psst.setString(count++, resource.getPermission());
                psst.setLong(count++, resource.getParentId());
                psst.setString(count++, resource.getParentIds());
                psst.setBoolean(count++, resource.getAvailable());
                return psst;
            }
        }, keyHolder);
        return resource;
    }

    @Override
    public Resource updateResource(Resource resource) {
        final String sql = "update sys_resource set name=?, type=?, url=?, permission=?, parent_id=?, parent_ids=?, available=? where id=?";
        //System.out.println("[SQL:]" + sql);
        jdbcTemplate.update(
                sql,
                resource.getName(), resource.getType().name(), resource.getUrl(), resource.getPermission(), resource.getParentId(), resource.getParentIds(), resource.getAvailable(), resource.getId());
        CacheHelper.cleanCache(CacheType.resource, resource.getId());
        return resource;
    }

    public void deleteResource(Long resourceId) {
        Resource resource = findOne(resourceId);
        final String deleteSelfSql = "delete from sys_resource where id=?";
        //System.out.println("[SQL:]" + deleteSelfSql);
        jdbcTemplate.update(deleteSelfSql, resourceId);
        CacheHelper.cleanCache(CacheType.resource, resourceId);
        final String deleteDescendantsSql = "delete from sys_resource where parent_ids like ?";
        //System.out.println("[SQL:]" + deleteDescendantsSql);
        jdbcTemplate.update(deleteDescendantsSql, resource.makeSelfAsParentIds() + "%");
    }


    @Override
    public Resource findOne(Long resourceId) {
    	Object cachedObj = CacheHelper.getCache(CacheType.resource, resourceId);
    	if (cachedObj != null) {
    		return (Resource)cachedObj;
    	}
    	
        final String sql = "select id, name, type, url, permission, parent_id, parent_ids, available from sys_resource where id=?";
        //System.out.println("[SQL:]" + sql);
        List<Resource> resourceList = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Resource.class), resourceId);
        if(resourceList.size() == 0) {
            return null;
        }
        Resource resource = resourceList.get(0);
        CacheHelper.setCache(CacheType.resource, resourceId, resource);
        return resource;
    }

    @Override
    public List<Resource> findAll() {
        final String sql = "select id, name, type, url, permission, parent_id, parent_ids, available from sys_resource order by concat(parent_ids, id) asc";
        //System.out.println("[SQL:]" + sql);
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper(Resource.class));
    }

}
